/*
 * $Id: Subtree.java,v 1.2 2004/10/06 20:09:17 jppietsch Exp $
 * Copyright (C) 2001 Jan-Peter Pietsch
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package de.jppietsch.prefedit;


import de.jppietsch.error.Log;
import de.jppietsch.error.Precondition;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;


/**
 * An immutable preferences tree which may be placed in the clipboard.
 *
 * @author Jan-Peter Pietsch
 * @version $Revision: 1.2 $
 */
public class Subtree extends AbstractTransferable {

    // constants

    // fields

    /**
     * Preferences node.
     */
    private Preferences node;

    /**
     * Name of this subtrees root.
     */
    private final String key;

    /**
     * List of {@link Subtree} representing the subnodes.
     */
    private final ArrayList subtrees = new ArrayList();

    /**
     * List of {@link Preference} representing the keys with their values.
     */
    private final ArrayList prefs = new ArrayList();

    // constructors

    /**
     * Constructs this Preference from a given preferences node and key.
     *
     * @param somePreferences the preferences node.
     */
    public Subtree(Preferences somePreferences) throws BackingStoreException {
        Precondition.argumentNotNull("somePreferences", somePreferences);

        node = somePreferences;
        key = node.name();

        String[] children = node.childrenNames();
        for (int i = 0; i < children.length; i++) {
            subtrees.add(new Subtree(node.node(children[i])));
        }

        String[] keys = node.keys();
        for (int i = 0; i < keys.length; i++) {
            prefs.add(new Preference(node, keys[i]));
        }
    }

    // overwritten methods

    /**
     * Returns a string representation of this object.
     *
     * @return A string representation of this object.
     */
    public String toString() {
        return toString(new StringBuffer(), "").toString();
    }

    /**
     * Copies this preferences subtree to the system clipboard and removes it.
     */
    public void cut() {
        super.cut();
        try {
            node.removeNode();
        } catch (BackingStoreException exception) {
            Log.caught(exception);
        }
        node = null;
    }

    // implemented methods

    /**
     * Returns a human presentable name for this class.
     *
     * @return A human presentable name for the concrete class.
     */
    protected String humanPresentableClassName() {
        return "Preferences subtree";


    }

    /**
     * Adds this transferable to the given preferences.
     *
     * @param somePreferences to which this is added.
     */
    protected void doPaste(Preferences somePreferences) {
        Preferences node = somePreferences.node(key);

        Iterator siter = subtrees.iterator();
        while (siter.hasNext()) {
            ((Subtree) siter.next()).doPaste(node);
        }

        Iterator piter = prefs.iterator();
        while (piter.hasNext()) {
            ((Preference) piter.next()).doPaste(node);
        }
    }

    // private methods

    /**
     * Recursive helper for {@link #toString()}.
     *
     * @param aBuffy   receives a string representation of this object.
     * @param anIndent is preceded before any line.
     * @return The given buffer filled with the requested string.
     */
    private StringBuffer toString(StringBuffer aBuffy, String anIndent) {
        String indent = anIndent + '\t';
        aBuffy.append(anIndent);
        aBuffy.append(key);
        aBuffy.append('\n');

        Iterator siter = subtrees.iterator();
        while (siter.hasNext()) {
            ((Subtree) siter.next()).toString(aBuffy, indent);
        }

        Iterator piter = prefs.iterator();
        while (piter.hasNext()) {
            aBuffy.append(anIndent);
            aBuffy.append(piter.next().toString());
            aBuffy.append('\n');
        }

        return aBuffy;
    }

}